package mornd.test8;

import mornd.test8.entity.Result;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author: mornd
 * @dateTime: 2023/5/8 - 18:38
 * 实现增强返回值类型（如果控制器方法返回User类型，则主动将它包装成Result类型）
 */

@ControllerAdvice
public class MyControllerAdvice implements ResponseBodyAdvice<Object> {


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 获取执行方法所在的类
        Class<?> containingClass = returnType.getContainingClass();
        //boolean present = containingClass.isAnnotationPresent(ResponseBody.class);
        /*
           spring 提供的注解工具类，不仅可以找到 controller 类上是否标注了 @ResponseBody
           还能在类上其它注解里面继续查找 @ResponseBody
           如果类上没有，则遍历它的接口、注解和超类。
           比如 @RestController 注解内就标注了 @ResponseBody 注解，此时也能返回 true
         */
        return (returnType.getMethodAnnotation(ResponseBody.class) != null ||
                AnnotationUtils.findAnnotation(containingClass, ResponseBody.class) != null);
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if(!(body instanceof Result)) {
            return new Result(200, "success", body);
        }
        return body;
    }
}
